package com.yunji.common.utils.uuid;

import com.yunji.common.utils.StringUtils;
import com.yunji.common.utils.TimeUtils;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Project: yunji-coffee
 * @Package: com.yunji.common.utils.uuid
 * @Title: UUIDUtils
 * @Description: History:
 * Date                     Version     Author          Summary
 * ============================================================
 * 2024-04-07 11:10:26      V1.0        HuaAo       新建类
 */
public class UUIDUtils {
    private UUIDUtils() {
        throw new IllegalStateException("Class Illegal Loading");
    }

    private static final SnowFlake SNOWFLAKE = new SnowFlake(2, 2, 2);

    private static final SerialCode SERIAL_ORDER_CODE = new SerialCode();
    private static final SerialCode SERIAL_TRADE_CODE = new SerialCode();
    private static final SerialCode SERIAL_REFUND_CODE = new SerialCode();
    private static final SerialCode SERIAL_PAYOUT_CODE = new SerialCode();
    private static final StockCode SERIAL_STORAGE_CODE = new StockCode();

    public static String quickUUID() {
        return String.valueOf(SNOWFLAKE.nextId());
    }

    /**
     * @return String 返回对应UUID
     * @Title randomUUID
     * @Desc 随机生成UUID
     * @Date 2024-04-07 12:03:43
     */
    public static String randomUUID() {
        return UUID.randomUUID().toString();
    }


    /**
     * @return String 返回对应UUID
     * @Title simpleUUID
     * @Desc 随机生成UUID, 去掉横线
     * @Date 2024-04-07 12:04:05
     */
    public static String simpleUUID() {
        return UUID.randomUUID().toString(true);
    }

    /**
     * @return String 返回对应UUID
     * @Title fastUUID
     * @Desc 获取随机UUID, 去掉横线 使用性能更好的ThreadLocalRandom生成UUID
     * @Date 2024-04-07 12:04:55
     */
    public static String fastUUID() {
        return UUID.fastUUID().toString();
    }

    /**
     * @return String 返回对应UUID
     * @Title rapidUUID
     * @Desc 获取随机UUID 使用性能更好的ThreadLocalRandom生成UUID
     * @Date 2024-04-07 12:04:55
     */
    public static String rapidUUID() {
        return UUID.fastUUID().toString(true);
    }

    // 机器标识
    private static final String MACHINE_CODE = "A";

    // 通用接口序列数
    private static final AtomicInteger SEQUENCE_COMMON_NUMS = new AtomicInteger(1);

    // 上传接口序列数
    private static final AtomicInteger SEQUENCE_UPLOAD_NUMS = new AtomicInteger(1);

    /**
     * @return String 返回对应UUID
     * @Title commonUUID
     * @Desc 获取通用随机ID
     * @Date 2024-04-07 12:20:23
     */
    public static String commonUUID() {
        return commonUUID(SEQUENCE_COMMON_NUMS, 3);
    }

    /**
     * @return String 返回对应UUID
     * @Title uploadUUID
     * @Desc 获取上传的随机ID
     * @Date 2024-04-07 12:22:54
     */
    public static String uploadUUID() {
        return commonUUID(SEQUENCE_UPLOAD_NUMS, 3);
    }

    /**
     * @return String 返回对应UUID
     * @Title commonUUID
     * @Desc 获取指定序号和长度的随机ID
     * @Date 2024-04-07 12:21:20
     * @Param atomicInt 当前序号
     * @Param length 数据长度
     */
    public static String commonUUID(AtomicInteger atomicInt, int length) {
        String result = TimeUtils.dateTimeNow();
        result += MACHINE_CODE;
        result += ordinal(atomicInt, length);
        return result;
    }

    /**
     * @return String 返回对应UUID
     * @Title ordinal
     * @Desc 累计序号
     * @Date 2024-04-07 12:20:33
     * @Param atomicInt 当前序号
     * @Param length 数据长度
     */
    private static synchronized String ordinal(AtomicInteger atomicInt, int length) {
        // 先取值再+1
        int value = atomicInt.getAndIncrement();
        // 如果更新后值>=10 的(length)幂次方则重置为1
        int maxSeq = (int) Math.pow(10, length);
        if (atomicInt.get() >= maxSeq) {
            atomicInt.set(1);
        }
        // 转字符串，用0左补齐
        return StringUtils.padl(value, length);
    }

    /**
     * @return String 交易序列号
     * @Title tradeCode
     * @Desc 交易序列号
     * @Date 2024-04-15 11:21:26
     */
    public static String tradeCode() {
        return 'T' + SERIAL_TRADE_CODE.nextId(5);
    }

    /**
     * @return String 交易序列号
     * @Title orderCode
     * @Desc 订单序列号
     * @Date 2024-04-15 11:21:49
     */
    public static String orderCode(String prefix) {
        return prefix + SERIAL_ORDER_CODE.nextId(5);
    }

    /**
     * @return String 交易序列号
     * @Title refundCode
     * @Desc 退款序列号
     * @Date 2024-04-15 11:21:49
     */
    public static String refundCode() {
        return 'R' + SERIAL_ORDER_CODE.nextId(5);
    }

    /**
     * @return String 交易序列号
     * @Title payoutCode
     * @Desc 提现序列号
     * @Date 2024-04-15 11:21:49
     */
    public static String payoutCode() {
        return 'P' + SERIAL_ORDER_CODE.nextId(5);
    }

    /**
     * 入库单序列号
     *
     * @return
     */
    public static String intoStorageCode() {
        return "RKD" + SERIAL_STORAGE_CODE.nextStockId(5);
    }

    /**
     * 出库单序列号
     *
     * @return
     */
    public static String outStorageCode() {
        return "CKD" + SERIAL_STORAGE_CODE.nextStockId(5);
    }

    /**
     * 调拨单序列号
     *
     * @return
     */
    public static String allocateCode() {
        return "DBD" + SERIAL_STORAGE_CODE.nextStockId(5);
    }

    /**
     * 报废单序列号
     *
     * @return
     */
    public static String discardCode() {
        return "BFD" + SERIAL_STORAGE_CODE.nextStockId(5);
    }

    /**
     * 坏返单序列号
     *
     * @return
     */
    public static String repairCode() {
        return "HFD" + SERIAL_STORAGE_CODE.nextStockId(5);
    }

    /**
     * 盘点单序列号
     *
     * @return
     */
    public static String stockTakeCode() {
        return "PDD" + SERIAL_STORAGE_CODE.nextStockId(5);
    }
}
